import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:flutter_book/data/model/yck/yck_rule_book_3_model.dart';
import 'package:flutter_book/api/api.dart';
import 'package:flutter_book/api/api_yck.dart';
import 'package:flutter_book/util/extensions/string_extensions.dart';

class SearchYckRuleBookUtil {
  late YckRuleBook3Model source;

  late String key;

  late int page;

  late String baseUrl;

  late Map headerMapF;
  late String book;

  var splitUrlRegex = RegExp(",\\s*(?=\\{)");

  // var pagePattern = Pattern("<(.*?)>")
  late String url;

  SearchYckRuleBookUtil(this.source, this.key, this.page, this.baseUrl, this.headerMapF, this.book);

  factory SearchYckRuleBookUtil.fromRule(YckRuleBook3Model source, String key, int page) =>
      SearchYckRuleBookUtil(source, key, page, source.bookSourceUrl, Map(), "").init();

  late String method;

  SearchYckRuleBookUtil init() {
    var ruleUrl = source.bookSourceUrl;
    var urlArray = ruleUrl.split(splitUrlRegex);
    url = getAbsoluteURL(baseUrl, urlArray[0]);

    if (urlArray.length > 1) {
      var json = JsonCodec();
      var option = json.decode(urlArray[1]);
      if (option["method"] != null) {
        method = option["method"];
      }
    }
    return this;
  }

  bool isAbsUrl(String it) {
    return it.toLowerCase().startsWith("http://") || it.toLowerCase().startsWith("https://");
  }

  /**
   * 获取绝对地址
   */
  String getAbsoluteURL(String baseURL, String relativePath) {
    if (isAbsUrl(relativePath)) {
      return relativePath;
    }
    if (baseURL.contains(',')) {
      var relativeUrl = relativePath;
      var absoluteUrl = Uri.parse(baseURL.substring(0, baseURL.indexOf(",")));
      relativeUrl = absoluteUrl.resolve(relativePath).toString();
      return relativeUrl;
    }
    return baseURL;
  }

  Future<String?> searchBooks() async {
    if (source.searchUrl == null) {
      "搜索地址有问题:$baseUrl".print;
      return null;
    }

    var uri = Uri.parse(baseUrl);

    //获取搜索地址
    var ruleUrl = _getRuleUrl(source.searchUrl!);

    try {
      return await analyzeRule(ruleUrl, uri);
    } catch (e) {
      "搜索地址解析错误:$baseUrl,\n${source.searchUrl},\n${source.bookSourceName},\n${e.toString()}".print;
      return null;
    }
  }

  String _getRuleUrl(String ruleUrl) {
    //将搜索地址中的 基础地址截取掉
    if (ruleUrl.contains(baseUrl)) {
      ruleUrl = ruleUrl.replaceAll(baseUrl, "");
    } else {
      if (ruleUrl.contains("http://") || ruleUrl.contains("https://")) {
        String httpString = "";
        if (ruleUrl.contains("http://")) {
          httpString = "http://";
        } else {
          httpString = "https://";
        }
        ruleUrl = ruleUrl.replaceAll(httpString, "");
        baseUrl = baseUrl.replaceAll("http://", "");
        baseUrl = baseUrl.replaceAll("https://", "");
        ruleUrl = ruleUrl.replaceAll(baseUrl, "");
        baseUrl = "$httpString$baseUrl";
        return ruleUrl;
      }
    }

    //将地址中的空格全部删除掉
    if (ruleUrl.contains(" ")) {
      ruleUrl = ruleUrl.replaceAll(" ", "");
    }
    //将地址中的{{ 替换成[[
    if (ruleUrl.contains("{{")) {
      ruleUrl = ruleUrl.replaceAll("{{", "[[");
    }
    //将地址中的}} 替换成]]
    if (ruleUrl.contains("}}")) {
      ruleUrl = ruleUrl.replaceAll("}}", "]]");
    }
    return ruleUrl;
  }

  Future<String?> analyzeRule(String ruleUrl, Uri uri) async {
    BaseOptions? option;

    var method = 'GET';
    late String data;
    data = '';

    //判断地址中没有 ,
    if (ruleUrl.contains(",{")) {
      var ruleUrlArray = ruleUrl.split(",{");
      if (ruleUrlArray.length < 2) {
        "搜索链接有误:$baseUrl$ruleUrl".print;
        return null;
      }
      //ruleUrlArray[0] 是 搜索地址
      ruleUrlArray[0] = ruleUrlArray[0].replaceAll("<", "");
      ruleUrlArray[0] = ruleUrlArray[0].replaceAll(">", "");
      ruleUrlArray[0] = ruleUrlArray[0].replaceAll(",", "");
      ruleUrlArray[0] = ruleUrlArray[0].replaceAll("[[page]]", "$page");
      ruleUrlArray[0] = ruleUrlArray[0].replaceAll("[[key]]", key);

      uri = Uri.parse((baseUrl + ruleUrlArray[0]));

      //ruleUrlArray[1] 是 上传的json 格式
      ruleUrlArray[1] = "{${ruleUrlArray[1]}";

      if (ruleUrlArray[1].contains("'")) {
        ruleUrlArray[1] = ruleUrlArray[1].replaceAll("'", "\"");
      }

      //有些对page 有做限制 在这里删除掉
      if (ruleUrlArray[1].contains("&offset")) {
        var offsetString = ruleUrlArray[1].substring(
            ruleUrlArray[1].indexOf("&offset"), ruleUrlArray[1].indexOf("\"", ruleUrlArray[1].indexOf("&offset")));
        ruleUrlArray[1] = ruleUrlArray[1].replaceAll(offsetString, "");
      }

      var dataMap = jsonDecode(ruleUrlArray[1]);

      if (dataMap['method'] != null && dataMap['method'].toString().toUpperCase() == 'POST'.toUpperCase()) {
        method = 'POST';
      }

      if (dataMap['body'] != null) {
        var body = dataMap["body"].replaceAll("[[key]]", key).replaceAll("[[page]]", "$page");
        if (method == 'POST') {
          data = body;
          if (data.contains("=")) {
            var array = data.split("&");
            String jsonString = "{";
            array.forEach((element) {
              var elementArray = element.split("=");
              if (elementArray.length < 2) {
                return;
              }
              jsonString += "\"${elementArray[0]}\":\"${elementArray[1]}\",";
            });
            jsonString = jsonString.substring(0, jsonString.length - 1);
            jsonString += "}";
            data = jsonString;
          }
        } else {
          uri = uri.replace(query: body);
        }
      }

      if (dataMap['headers'] != null) {
        if (dataMap['headers'] is String) {
          try {
            option = BaseOptions();
            option.headers = JsonCodec().decoder.convert(dataMap['headers']);
          } catch (e) {
            option = null;
          }
        } else if (dataMap['headers'] is Map<String, dynamic>) {
          option = BaseOptions();
          option.headers = dataMap['headers'];
        }
      }
    } else {
      uri = Uri.parse((baseUrl + ruleUrl).replaceAll("[[key]]", key).replaceAll("[[page]]", "$page"));
    }


    try {
      var response = await requestYckApi(uri, data: data, requestMethod: method, baseOptions: option);

      if (response == null) {
        "数据获取失败:${uri.toString()},${data.toString()},${method}".print;
      } else {
        return response.toString();
      }
    } catch (e) {
      "发生错误".print;
    }
    return null;
  }



  static Future<String> searchBookChapter(String url) async {
    // var option = BaseOptions();
    var uri = Uri.parse(url.replaceAll('@', '?'));

    try {
      // var dio = new Dio(option);
      // (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
      //   // config the http client
      //   client.findProxy = (uri) {
      //     //proxy all request to localhost:8888
      //     return "PROXY localhost:8888"; //这里将localhost设置为自己电脑的IP，其他不变，注意上线的时候一定记得把代理去掉
      //   };
      //   // you can also create a HttpClient to dio
      //   // return HttpClient();
      // };
      // var response = await dio.postUri(uri);
      // if (response.statusCode == 200) {
      //   // print(uri);
      //   // print(response);
      //   return response.toString();
      // }
    } catch (e) {
      print(url);
      print(e);
    }
    return '';
  }

  String getSearchUrl() {
    return getAbsoluteURL(baseUrl, source.bookSourceUrl);
  }
}
